#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <time.h>
/*
 * El siguiente codigo tiene por objetivo mostrar como realizar una
 * exclusion mutua usando un pipe para sincronizar dos procesos.
 * El ejemplo es bastante sencillo. Ambos procesos intentan acceder
 * a la zona de exclusion, y dentro de ella simulan hacer algo 
 * mediante un llamado a sleep()
 */
int main(){
    //file descriptors para el pipe
    int fdesc[2];
    char wdata = 'L';
    char rdata;
	int lock;
	
    //abrimos el pipe
    if(pipe(fdesc) == -1){ 
        printf("Pipe error");
        exit(EXIT_FAILURE);
    }

	//inicializo el pipe
	while(write(fdesc[1], &wdata, 1) != 1){}
	
	pid_t pid = fork();
	
	if(pid==-1){
	    printf("Error en el fork");
	    exit(EXIT_FAILURE);
	}
	
	if(pid != 0){
	    /*Codigo del padre*/
	    srand(time(NULL));
	    while(1){
            //Mientras no se lea del pipe, no se puede entrar
	        while((lock = read(fdesc[0], &rdata, 1)) != 1){}
	        printf("A entro en la zona de exclusion\n");
	        //simulamos que hacemos algo dentro de la zona de exclusion...
	        sleep(rand()%5);
	        printf("A esta saliendo de la zona de exclusion\n");
	        while((lock = write(fdesc[1], &wdata, 1)) != 1){}
            sleep(rand()%3);
	    }
	}
	else{
	    /*Codigo del hijo*/
        srand(time(NULL)+5);
	    while(1){
            //Mientras no se lea del pipe, no se puede entrar
	        while((lock = read(fdesc[0], &rdata, 1)) != 1){}
	        printf("\tB entro en la zona de exclusion\n");
	        //simulamos que hacemos algo dentro de la zona de exclusion...	        
	        sleep(rand()%3);
	        printf("\tB esta saliendo de la zona de exclusion\n");
	        while((lock = write(fdesc[1], &wdata, 1)) != 1){}
            sleep(rand()%5);       
	   }

	}
	return 0;
}
